home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / text / misc / mpage.lha / mpage / file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-25  |  9.1 KB  |  340 lines

  1. /*
  2.  * file.c
  3.  */
  4.  
  5. /*
  6.  * mpage:    a program to reduce pages of print so that several pages
  7.  *           of output appear on one printed page.
  8.  *
  9.  * Written by:
  10.  *   ...!uunet!\                       Mark Hahn, Sr Systems Engineer
  11.  *              >pyrdc!mark            Pyramid Technology Corporation
  12.  * ...!pyramid!/                       Vienna, Va    (703)848-2050
  13.  *
  14.  *
  15.  * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
  16.  * Copyright (c) 1994-1997 Marcel J.E. Mol, The Netherlands
  17.  *                    marcel@mesa.nl
  18.  *  
  19.  *     Permission is granted to anyone to make or distribute verbatim
  20.  *     copies of this document as received, in any medium, provided
  21.  *     that this copyright notice is preserved, and that the
  22.  *     distributor grants the recipient permission for further
  23.  *     redistribution as permitted by this notice.
  24.  *
  25.  */
  26.  
  27.  
  28. #include "mpage.h"
  29.  
  30.  
  31. /*
  32.  * do_file converts one file into postscript for output.  The file type is
  33.  * determined then the proper conversion routine is selected.
  34.  */
  35. void
  36. do_file(fname, asheet, outfd)
  37.  char *fname;
  38.  struct sheet *asheet;
  39.  FILE *outfd;
  40. {
  41.     FILE *fd;
  42.  
  43.     /*
  44.      * if we have the pr option, then we have to assume it's a text file
  45.      */
  46.     if (opt_pr) {
  47.         do_pr_file(fname, asheet, outfd);
  48.         return;
  49.     }
  50.     /*
  51.      * if not using pr(1), open fname and try to figure out what type of
  52.      * file it is
  53.      */
  54.     if ((fd = fopen(fname, "r")) == NULL) {
  55.         fprintf(stderr, "%s: cannot open %s\n", MPAGE, fname);
  56.         perror(MPAGE);
  57.         return;
  58.     }
  59.  
  60.     /*
  61.      * is input type forced?
  62.      */
  63.     switch (opt_input) {
  64.     case IN_ASCII:  do_text_doc(fd, asheet, outfd, fname);
  65.             break;
  66.     case IN_PS:     do_ps_doc(fd, asheet, outfd, fname);
  67.             break;
  68.         /* Default figure out ourselfes */
  69.     }
  70.  
  71.     /*
  72.      * check for the cutomary characters that flag a postscript file
  73.      */
  74.     if (ps_check(fd))
  75.         /*
  76.          * found the flag signaling PS input
  77.          */
  78.         do_ps_doc(fd, asheet, outfd, fname);
  79.     else
  80.         /*
  81.          * no postscript flag, print the ascii text
  82.          */
  83.         do_text_doc(fd, asheet, outfd, fname);
  84.  
  85.     (void) fclose(fd);
  86.  
  87.     return;
  88.  
  89. } /* do_file */
  90.  
  91.  
  92.  
  93. /*
  94.  * do_file processes one text file into postscript, but first runs the file
  95.  * through pr(1).
  96.  */
  97. void
  98. do_pr_file(fname, asheet, outfd)
  99.  char *fname;
  100.  struct sheet *asheet;
  101.  FILE *outfd;
  102. {
  103.     FILE *fd;
  104.     char command[LINESIZE];
  105.  
  106.     /*
  107.      * build the proper command based upon a specified
  108.      * header or not
  109.      */
  110.     if (opt_header != NULL)
  111.         (void)sprintf(command, "%s -l%d -w%d -h \"%s\" %s", prprog,
  112.                   asheet->sh_plength, asheet->sh_cwidth, opt_header, fname);
  113.     else
  114.         (void)sprintf(command, "%s -l%d -w%d %s", prprog,
  115.                   asheet->sh_plength, asheet->sh_cwidth, fname);
  116.     /*
  117.      * open a pipe to the proper pr(1) command, and pr provides
  118.      * us with the input
  119.      */
  120.     if ((fd = popen(command, "r")) == NULL) {
  121.         fprintf(stderr, "%s: cannot create pipe for '%s'\n", MPAGE, command);
  122.         perror(MPAGE);
  123.     }
  124.     else {
  125.         do_text_doc(fd, asheet, outfd, command);
  126.         (void)pclose(fd);
  127.     }
  128.  
  129.     return;
  130.  
  131. } /* do_pr_file */
  132.  
  133.  
  134.  
  135. /*
  136.  * do_stdin uses do_????_doc to process the standard input
  137.  */
  138. void
  139. do_stdin(asheet, outfd)
  140.  struct sheet *asheet;
  141.  FILE *outfd;
  142. {
  143.     FILE *fd;
  144.     char command[LINESIZE];
  145.     char tmpfile[LINESIZE];
  146.     char buffer[LINESIZE];
  147.     int incnt, outcnt;
  148.  
  149.     if (opt_pr) {
  150.         Debug(DB_STDIN, "%%do_stdin: pr option selects text\n", 0);
  151.         /*
  152.          * if pr(1) is to be used we need to read the input
  153.          * and pass it to a pr(1) command which will write
  154.          * a temporary file; this temporary file will then
  155.          * be used as input to the do_doc routine
  156.          */
  157.         (void)strcpy(tmpfile, "/usr/tmp/mpageXXXXXX");
  158.         (void)mktemp(tmpfile);
  159.         if (opt_header != NULL)
  160.             (void)sprintf(command, "pr -l%d -w%d -h \"%s\"> %s",
  161.                       asheet->sh_plength, asheet->sh_cwidth,
  162.                       opt_header, tmpfile);
  163.         else
  164.             (void)sprintf(command, "pr -l%d -w%d > %s",
  165.                       asheet->sh_plength, asheet->sh_cwidth, tmpfile);
  166.         /*
  167.          * open a pipe to the pr(1) command which will create a
  168.          * temporary file for convertin into PS
  169.          */
  170.         if ((fd = popen(command, "w")) == NULL) {
  171.             fprintf(stderr, "%s: cannot create pipe for '%s'\n",
  172.                 MPAGE, command);
  173.             perror(MPAGE);
  174.             return;
  175.         }
  176. #ifdef DEBUG
  177.         errno = 0;
  178.         Debug(DB_STDIN, "%% sizeof buffer == %d\n", sizeof buffer);
  179. #endif
  180.         /*
  181.          * read input to mpage and pass it onto the pr(1) command
  182.          */
  183.         do {
  184.             incnt = fread(buffer, 1, sizeof buffer, stdin);
  185.             outcnt = fwrite(buffer, 1, incnt, fd);
  186.             Debug(DB_STDIN, "%% incnt == %d,", incnt);
  187.             Debug(DB_STDIN, " outcnt == %d,", outcnt);
  188.             Debug(DB_STDIN, " errno == %d\n", errno);
  189.         } while (incnt && outcnt);
  190.         Debug(DB_STDIN, "%% Done with while\n", 0);
  191.         (void)pclose(fd);
  192.         Debug(DB_STDIN, "%% closed pipe, looking for tmpfile\n", 0);
  193.         /*
  194.          * now open the temporary file and use do_doc to
  195.          * convert it to PS
  196.          */
  197.         if ((fd = fopen(tmpfile, "r")) == NULL) {
  198.             fprintf(stderr, "%s: cannot open %s\n", MPAGE, tmpfile);
  199.             perror(MPAGE);
  200.         } else {
  201.             Debug(DB_STDIN, "%% got tmpfile, now do_doc\n", 0);
  202.             do_text_doc(fd, asheet, outfd, command);
  203.             (void)fclose(fd);
  204.         }
  205.         /*
  206.          * tidy up by removing our temp file
  207.          */
  208.         Debug(DB_STDIN, "%% now remove '%s'\n", tmpfile);
  209.         (void)unlink(tmpfile);
  210.     }
  211.     else {
  212.         /*
  213.          * check for the cutomary flag at the start of postscript files
  214.          */
  215.         if (ps_check(stdin)) {
  216.             /*
  217.              * found the flag signaling PS input
  218.              */
  219.             Debug(DB_STDIN, "%%do_stdin: is postscript\n", 0);
  220.             do_ps_doc(stdin, asheet, outfd, "stdin");
  221.         }
  222.         else {
  223.             /*
  224.              * no postscript flag, print the ascii text
  225.              */
  226.             Debug(DB_STDIN, "%%do_stdin: not postscript\n", 0);
  227.             do_text_doc(stdin, asheet, outfd, "stdin");
  228.         }
  229.     }
  230.  
  231.     return;
  232.  
  233. } /* do_stdin */
  234.  
  235.  
  236.  
  237. /*
  238.  * do_sheets() is called from do_xxx_doc() to render the sheets;
  239.  * it does sheet selection and reversal.
  240.  */
  241. void
  242. do_sheets(sheetfunc, inf, asheet, outf)
  243.     int (*sheetfunc)();
  244.     FILE *inf;
  245.     struct sheet *asheet;
  246.     FILE *outf;
  247. {
  248.     FILE *nullf = NULL;
  249.     register int sheetno;
  250.  
  251. #define    WANTED(sn) \
  252.     (sn >= opt_first && (opt_alt <= 1 || (sn - opt_first) % opt_alt == 0))
  253.  
  254.     if (opt_last == 0)
  255.         opt_last = MAXINT;
  256.  
  257.     if (opt_alt > 1 || opt_first > 1)
  258.         nullf = fopen("/dev/null", "w");
  259.  
  260.     if (opt_reverse) {
  261.         FILE *revf;
  262.         long *pagebase;
  263.         int pageroom;
  264.  
  265.         revf = tmpfile();
  266.         if (revf == NULL) {
  267.             fprintf(stderr, "%s: can't create temporary file\n", MPAGE);
  268.             exit(1);
  269.         }
  270.         pageroom = 50;
  271.         pagebase = (long *)malloc(pageroom * sizeof(long));
  272.         if(pagebase == NULL) {
  273.             fprintf(stderr, "%s: can't malloc 50 words\n", MPAGE);
  274.             exit(1);
  275.         }
  276.         pagebase[0] = 0;
  277.  
  278.         for (sheetno = 1; sheetno <= opt_last; ) {
  279.             if ((*sheetfunc)(inf, asheet, WANTED(sheetno) ? revf : nullf)
  280.                   == FILE_EOF)
  281.                 break;
  282.  
  283.             if (ferror(revf))
  284.                 break;
  285.  
  286.             pagebase[sheetno++] = ftell(revf);
  287.             if (sheetno >= pageroom) {
  288.                 pageroom *= 4;
  289.                 pagebase = (long *)realloc(pagebase, pageroom * sizeof(long));
  290.                 if (pagebase == NULL) {
  291.                     fprintf(stderr, "%s: can't malloc %d words\n",
  292.                                     MPAGE, pageroom);
  293.                     exit(1);
  294.                 }
  295.         
  296.             }
  297.         }
  298.  
  299.         if (ferror(revf))
  300.             fprintf(stderr, "%s: error writing to temporary file\n", MPAGE);
  301.         else {
  302.             pagebase[sheetno] = ftell(revf);
  303.             rewind(revf);
  304.  
  305.             while (--sheetno >= 0) {
  306.                 register int i, n;
  307.                 char buf[BUFSIZ];
  308.  
  309.                 fseek(revf, pagebase[sheetno], 0);
  310.                 for(i = pagebase[sheetno+1]-pagebase[sheetno]; i>0; i-=n) {
  311.                     n = i < BUFSIZ ? i : BUFSIZ;
  312.                     if (fread(buf, n, 1, revf) != 1) {
  313.                         fprintf(stderr, "%s: Premature EOF on temp file\n",
  314.                         MPAGE);
  315.                         break;
  316.                     }
  317.                     (void) fwrite(buf, n, 1, outf);
  318.                 }
  319.             }
  320.         }
  321.         fclose(revf);
  322.         free(pagebase);
  323.  
  324.     }
  325.     else {
  326.         /* Normal, non-reversed pages */
  327.         sheetno = 1;
  328.         while (sheetno <= opt_last &&
  329.                (*sheetfunc)(inf, asheet, WANTED(sheetno) ?
  330.                         outf : nullf) != FILE_EOF)
  331.             sheetno++;
  332.     }
  333.  
  334.     if (nullf)
  335.         fclose(nullf);
  336.  
  337.     return;
  338.  
  339. } /* do_sheets */
  340.